Ext.define('MyExtend.lib.TreeFilter', {
  filterByText: function (text) {
    this.filterBy(text, 'text');
  },
  /**
   * 根据字符串过滤所有的节点，将不符合条件的节点进行隐藏.
   * @param 查询字符串.
   * @param 要查询的列.
   */
  filterBy: function (text, by) {

    this.clearFilter();
    console.log(this.clearFilter())
    var view = this.getView(),
      me = this,
      nodesAndParents = [];
      console.log(view)
    // 找到匹配的节点并展开.
    // 添加匹配的节点和他们的父节点到nodesAndParents数组.
    this.getRootNode().cascadeBy(function (tree, view) {
      var currNode = this;

      if (currNode && currNode.data[by] && currNode.data[by].toString().toLowerCase().indexOf(text.toLowerCase()) > -1) {
        me.expandPath(currNode.getPath());

        while (currNode.parentNode) {
          nodesAndParents.push(currNode.id);
          currNode = currNode.parentNode;
        }
      }
    }, null, [me, view]);

    // 将不在nodesAndParents数组中的节点隐藏
    this.getRootNode().cascadeBy(function (tree, view) {
      var uiNode = view.getNodeByRecord(this);

      if (uiNode && !Ext.Array.contains(nodesAndParents, this.id)) {
        Ext.get(uiNode).setDisplayed('none');
      }
    }, null, [me, view]);
  },


  clearFilter: function () {
    var view = this.getView();

    this.getRootNode().cascadeBy(function (tree, view) {
      var uiNode = view.getNodeByRecord(this);

      if (uiNode) {
        Ext.get(uiNode).setDisplayed('table-row');
      }
    }, null, [this, view]);
  }
});

/**
 * rootVisible        是否显示根节点
 * multiSelect        是否多选，默认单选
 * multiCascade       是否级联选择，级联选择选择子节点会=带上父节点,默认级联选择
 * selectNodeModel    选择树结点的模式，all：所有结点都可选中
 *                                     exceptRoot:除根结点，其它结点都可选(默认)
 *                                     folder:只有目录（非叶子和非根结点）可选
 *                                     leaf：只有叶子结点可选
 */

Ext.define('Ext.ux.ComboBoxTree', {
  extend: 'Ext.form.field.Picker',
  requires: ['Ext.tree.Panel', 'MyExtend.lib.TreeFilter'],
  alias: ['widget.comboboxtree'],
  multiSelect: false,
  multiCascade: true,
  rootVisible: true,
  submitValue: '',
  pathValue: '',
  pathArray: [],
  selectNodeModel: 'all',
  initComponent: function () {
    var self = this;
    self.selectNodeModel = Ext.isEmpty(self.selectNodeModel) ?
      'all' :
      self.selectNodeModel;
    self.multiSelect = Ext.isEmpty(self.multiSelect) ?
      false :
      self.multiSelect;
    self.multiCascade = Ext.isEmpty(self.multiCascade) ?
      true :
      self.multiCascade;
    self.rootVisible = Ext.isEmpty(self.rootVisible) ?
      true :
      self.rootVisible;
    Ext.apply(self, {
      fieldLabel: self.fieldLabel,
      labelWidth: self.labelWidth

    });
    // self.store.load();
    self.callParent();
  },
  createPicker: function () {
    var self = this;

    var treeFilter = new MyExtend.lib.TreeFilter();
    var timeOutId = null;
    var hiddenPkgs = [];

    var findByKeyWordFiler = function (node, event) {
      console.log(node)
      console.log(event)
      clearTimeout(timeOutId); // 清除timeOutId  
      // tree.expandAll(); // 展开树节点  
      // 为了避免重复的访问后台，给服务器造成的压力，采用timeOutId进行控制，如果采用treeFilter也可以造成重复的keyup  
      timeOutId = setTimeout(function () {
        // 获取输入框的值  
        var text = node.getValue();
        // 根据输入制作一个正则表达式，'i'代表不区分大小写  
        var re = new RegExp(Ext.escapeRe(text), 'i');
        // 先要显示上次隐藏掉的节点  
        Ext.each(hiddenPkgs, function (n) {
          n.ui.show();
        });
        hiddenPkgs = [];
        console.log(text)
        if (text != "") {
          treeFilter.filterByText(text) 
          // treeFilter.filterBy(function (n) {
          //   // 只过滤叶子节点，这样省去枝干被过滤的时候，底下的叶子都无法显示  
          //   return !n.isLeaf() || re.test(n.text);
          // });
          // 如果这个节点不是叶子，而且下面没有子节点，就应该隐藏掉  
          tree.root.cascade(function (n) {
            if (n.id != '0') {
              if (!n.isLeaf() && judge(n, re) == false && !re.test(n.text)) {
                hiddenPkgs.push(n);
                n.ui.hide();
              }
            }
          });
        } else {
          treeFilter.clear();
          return;
        }
      }, 500);
    }

    self.picker = Ext.create('Ext.tree.Panel', {
      height: self.treeHeight == null ? 200 : self.treeHeight,
      autoScroll: true,
      floating: true,
      focusOnToFront: false,
      shadow: true,
      ownerCt: this.ownerCt,
      useArrows: false,
      store: self.store,
      rootVisible: this.rootVisible,
      tbar: [' ',
        new Ext.form.TextField({
          width: 330,
          emptyText: '请输入关键字检索',
          enableKeyEvents: true,
          listeners: {
            keyup: function (node, event) {
              findByKeyWordFiler(node, event);
            },
            scope: this
          }
        })
      ],
      viewConfig: {
        onCheckboxChange: function (e, t) {
          if (self.multiSelect) {
            var item = e.getTarget(this.getItemSelector(), this.getTargetEl()),
              record;
            if (item) {
              record = this.getRecord(item);
              var check = !record.get('checked');
              record.set('checked', check);
              if (self.multiCascade) {
                if (check) {
                  record.bubble(function (parentNode) {
                    if ('全部' != parentNode.get('text')) {
                      parentNode.set('checked', true);
                    }
                  });
                  record.cascadeBy(function (node) {
                    node.set('checked', true);
                    node.expand(true);
                  });
                } else {
                  record.cascadeBy(function (node) {
                    node.set('checked', false);
                  });
                  record.bubble(function (parentNode) {
                    if ('Root' != parentNode.get('text')) {
                      var flag = true;
                      for (var i = 0; i < parentNode.childNodes.length; i++) {
                        var child = parentNode.childNodes[i];
                        if (child.get('checked')) {
                          flag = false;
                          continue;
                        }
                      }
                      if (flag) {
                        parentNode
                          .set('checked', false);
                      }
                    }
                  });
                }
              }
            }
            var records = self.picker.getView().getChecked(),
              names = [],
              values = [];
            Ext.Array.each(records, function (rec) {
              names.push(rec.get(self.displayField));
              values.push(rec.get(self.valueField));
            });
            self.submitValue = values.join(',');
            self.setValue(values.join(','));
            self.setRawValue(names.join(','))
          }
        }
      }
    });
    self.picker.on({
      itemclick: function (view, recore, item, index, e, object) {
        var selModel = self.selectNodeModel;
        var isLeaf = recore.data.leaf;
        var isRoot = recore.data.root;
        var view = self.picker.getView();
        if (!self.multiSelect) {
          if ((isRoot) && selModel != 'all') {
            return;
          } else if (selModel == 'exceptRoot' && isRoot) {
            return;
          } else if (selModel == 'folder' && isLeaf) {
            return;
          } else if (selModel == 'leaf' && !isLeaf) {
            var expand = recore.get('expanded');
            if (expand) {
              view.collapse(recore);
            } else {
              view.expand(recore);
            }
            return;
          }

          self.submitValue = recore.get(self.valueField);
          self.setValue(recore.get(self.valueField));
          self.setRawValue(recore.get(self.displayField));
          self.eleJson = Ext.encode(recore.raw);
          self.collapse();
        }
      }
    });
    return self.picker;
  },
  listeners: {
    expand: function (field, eOpts) {
      var picker = this.getPicker();
      if (!this.multiSelect) {
        if (this.pathValue != '') {
          picker.expandPath(this.pathValue, 'id', '/', function (bSucess, oLastNode) {
            picker.getSelectionModel().select(oLastNode);
          });
        }
      } else {
        if (this.pathArray.length > 0) {
          for (var m = 0; m < this.pathArray.length; m++) {
            picker.expandPath(this.pathArray[m], 'id', '/',
              function (bSucess, oLastNode) {
                oLastNode.set('checked', true);
              });
          }
        }
      }

      var rootNode = this.store.getRootNode();
      if (rootNode && rootNode.childNodes.length === 1) {
        var rootNode_child = rootNode.childNodes[0];
        picker.expandPath(rootNode_child.getPath())
      }
    }
  },
  clearValue: function () {
    this.setDefaultValue('', '');
  },

  getEleJson: function () {
    if (this.eleJson == undefined) {
      this.eleJson = [];
    }
    return this.eleJson;
  },
  getRawValue: function () {
    if (this.rawValue == undefined) {
      this.rawValue = '';
    }
    return this.rawValue;
  },
  getValue: function () {
    if (this.value == undefined) {
      this.value = '';
    }
    return this.submitValue;
  },
  getSubmitValue: function () {
    if (this.submitValue == undefined) {
      this.submitValue = '';
    }
    return this.submitValue;
  },
  getDisplayValue: function () {
    if (this.rawValue == undefined) {
      this.rawValue = '';
    }
    return this.value;
  },
  reset: function () {
    this.setValue(this.originalValue);
    this.setRawValue(this.originalValue);
    this.clearInvalid();
  },
  setPathValue: function (pathValue) {
    this.pathValue = pathValue;
  },
  setPathArray: function (pathArray) {
    this.pathArray = pathArray;
  },
  setValue: function (value) {
    if (value != undefined) {
      var me = this,
        ds = me.store;
      var node = ds.getNodeById(value);
      if (node == undefined) {
        me.value = value;
        me.submitValue = value;
        me.setRawValue(value);
      } else {
        me.value = node.get(this.valueField);
        me.submitValue = node.get(this.valueField);
        me.setRawValue(node.get(this.displayField));
      }
    }
  },
  setDefaultValue: function (submitValue, displayValue) {
    this.submitValue = submitValue;
    this.setValue(displayValue);
    this.eleJson = undefined;

    this.pathArray = [];
  },
  alignPicker: function () {
    var me = this,
      picker, isAbove, aboveSfx = '-above';
    if (this.isExpanded) {
      picker = me.getPicker();
      if (me.matchFieldWidth) {
        picker.setWidth(me.bodyEl.getWidth());
      }
      if (picker.isFloating()) {
        picker.alignTo(me.inputEl, "", me.pickerOffset); // ""->tl
        isAbove = picker.el.getY() < me.inputEl.getY();
        me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
        picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
      }
    }
  }
});